function love.load()
	require "client"
	love.graphics.setMode(640,480,false,true,0)
	love.graphics.setCaption("UP")
	ww,wh,fs,vs,aa=love.graphics.getMode()
	state=0
	frames=0
	cx=0
	cy=0
	pinfo={ }
	pinfo[1]={p1x=50,p1y=50,p2x=120,p2y=50}
	k_string=""
	c_string=""
	pre=""
	connected=""
	console_log={}
	jump=true
	_edit=false
	_debug=false
	net.event("first",function(data)
		pre="f"
		print("received master player status")
	end )
	net.event("last",function(data)
		pre=""
		print("received lower player status")
	end)
	net.action("state",function(data)
		state=tonumber(data)
		print("received state call "..data)
	end )
	net.action("mapid",function(data)
		r=tonumber(data)
		if pre=="" then
		player.x,player.y=pinfo[r].p2x,pinfo[r].p2y
		print("lower priority player, setting x to "..pinfo[r].p2x..","..pinfo[r].p2y)
		else
		player.x,player.y=pinfo[r].p1x,pinfo[r].p1y
		print("higher priority player, setting x to "..pinfo[r].p1x..","..pinfo[r].p1y)
		end
		print("received map id "..data)
	end)
	net.action("update",function(data)
		nx,ny=data:match("(%S+)%s(%S+)")
		nx,ny=nx:gsub("bz","-"),ny:gsub("bz","-")
		nx,ny=tonumber(nx),tonumber(ny)
		otherplayer.x=nx
		otherplayer.y=ny
	end)
	-- default map
	edit_objects={}
	edit_objects[0]={x=0,y=0,w=80,h=80,type="newobj",c={50,50,150,150}}
	edit_relx=0
	edit_rely=0
	edit_sid=0
	pinfo={ }
	pinfo[1]={p1x=50,p1y=50,p2x=120,p2y=50}
	wall={}
	wall[5]={x=200,y=350,w=400,h=80,c={100,100,100,240},r=1} -- ground
	wall[1]={x=0,y=350,w=130,h=80,c={100,100,100,240},r=1} -- ground 2
	wall[2]={x=200,y=200,w=200,h=150,c={150,100,100,240},r=1} -- big boxy platform
	wall[3]={x=300,y=50,h=50,w=100,c={100,100,255,250},r=1} -- goal/high up block
	wall[4]={x=130,y=350,w=70,h=80,c={255,100,100,250},r=1} -- move block 1
	wall[6]={x=100,y=680,w=600,h=80,c={50,255,50,230},r=1} -- ground 2-2
	wall[7]={x=380,y=100,w=20,h=100,c={255,0,0,190},r=1} -- person 2 gate
	wall[8]={x=380,y=-190,w=20,h=260,c={80,80,80,200},r=1} -- anti cheat
	button={ }
	binds={ }
	button[1]={x=250,y=175,w=75,h=25,xx=250,yy=175,inc=20,a=function() -- goal button
		if wall[4].y>280 then
			if not plyat(wall[4].x,wall[4].y-1,wall[4].w,wall[4].h) then
				wall[4].y=wall[4].y-1
			else
				if not wallat(plyat(wall[4].x,wall[4].y-1,70,80).player.x,plyat(wall[4].x,wall[4].y-1,70,80).player.y-1,64,64,true) then
					plyat(wall[4].x,wall[4].y-1,70,80).player.y=plyat(wall[4].x,wall[4].y-1,70,80).player.y-0.5
					wall[4].y=wall[4].y-1
				end
			end
		end
	end,n=function()
		if wall[4].y<350 then
			wall[4].y=wall[4].y+0.5
		end
	end,c={50,50,180,180},_a=function() return end,_n=function() return end,down=false,r=1}
	button[2]={x=320,y=30,w=45,h=25,xx=320,yy=25,inc=20,a=function() -- goal button 2
		if wall[7].y>0 then
			if not plyat(wall[7].x,wall[7].y-1,wall[7].w,wall[7].h) then
				wall[7].y=wall[7].y-1
			else
				if not wallat(plyat(wall[7].x,wall[7].y-1,20,70).player.x,plyat(wall[7].x,wall[7].y-1,20,70).player.y-1,64,64,true) then
					plyat(wall[7].x,wall[7].y-1,20,70).player.y=plyat(wall[7].x,wall[7].y-1,20,70).player.y-1
					wall[7].y=wall[7].y-1
				end
			end
		end
	end,n=function()
		if wall[7].y<100 then
			wall[7].y=wall[7].y+2
		end
	end,c={50,180,50,180},_a=function() return end,_n=function() return end,down=false,r=1}
	button[3]={x=150,y=660,w=50,h=25,xx=150,yy=660,inc=15,a=function() -- goal button 3
		if wall[4].y>190 then
			if not plyat(wall[4].x,wall[4].y-1,wall[4].w,wall[4].h) then
				wall[4].y=wall[4].y-1
			else
				if not wallat(plyat(wall[4].x,wall[4].y-1,20,70).player.x,plyat(wall[4].x,wall[4].y-1,20,70).player.y-1,64,64,true) then
					plyat(wall[4].x,wall[4].y-1,20,70).player.y=plyat(wall[4].x,wall[4].y-1,20,70).player.y-1
					wall[4].y=wall[4].y-1
				end
			end
		end
	end,n=function()
		if wall[4].y<100 then
			wall[4].y=wall[4].y+2
		end
	end,c={180,50,50,180},_a=function() return end,_n=function() return end,down=false,r=1}
	-- end mapdata
	otherplayer={x=0,y=0}
	player={x=0,y=0,vspeed=0}
	--[[meter=love.physics.setMeter(64)
	world=love.physics.newWorld(0,9*64,false)
	body1=love.physics.newBody(world,50,2800,"dynamic")
	shape1=love.physics.newRectangleShape(80,80)
	fix1=love.physics.newFixture(body1,shape1,5)
	body2=love.physics.newBody(world,50,2800,"dynamic")
	shape2=love.physics.newRectangleShape(80,80)
	fix2=love.physics.newFixture(body2,shape2,5)
	--world:setCallbacks(function() end,function() end,preSolve,function() end)
	floor1=love.physics.newBody(world,0,2990,"static")
	fshape1=love.physics.newRectangleShape(640,150)
	ffi1=love.physics.newFixture(floor1,fshape1)]]--
end
function wallat(x,y,w,h,ply)
	for k,v in pairs(wall) do
	if v.r==r then
		if not w then
			if x>v.x and x<v.x+v.w then
				if y>v.y and y< v.y + v.h then
					return v
				end
			end
		else
			if x+w>v.x and x<v.x+v.w then
				if y+h>v.y and y<v.y+v.h then
					return v
				end
			end
		end
	end
	end
	if w then
		if ply then
			if x+w>otherplayer.x and x<otherplayer.x+64 then
				if y<otherplayer.y+64 and y+h>otherplayer.y then
					return {x=otherplayer.x,y=otherplayer.y,w=64,h=64}
				end
			end
		end
	end
	return false
end
function console(str)
	str=str.." "
	str,para=str:match("^(%S+)%s(.*)")
	if not str then return end
	if para then
	param={}
	repeat
		param[#param+1],ex=para:match("(%S+)%s(%S*)")
		if ex then
			para=ex
		end
	until para:match("%s")==nil
	end
	if str=="edit_toggle" then
		_edit=not _edit
		if _edit then
			state=2 
			wall={ }
			player.x=100
			player.y=100
			otherplayer.x=200
			otherplayer.y=100
			button={ }
			edit_objects[#edit_objects+1]={type="player",x=100,y=100,w=64,h=64,obj=player,c={255,0,0,130}}
			edit_objects[#edit_objects+1]={type="player",x=200,y=100,w=64,h=64,obj=otherplayer,c={0,0,255,130}}
		else
			if connected then
				net.close()
			end
			state=0
		end
		console_logadd("map editor turned "..onoff(_edit))
		return
	end
	if str=="clear" then
		for i=1,10 do console_logadd("") end
	end
	if str=="state" then
		state=tonumber(param[1])
	end
	if str=="edit_savelevel" then
		console_logadd("compiling level..")
		newm=""
		newm=edit_objects[2].x.." "..edit_objects[2].y.." "..edit_objects[3].x.." "..edit_objects[3].y.." "
		for k,v in pairs(wall) do
			newm=newm.."x:"..v.x..";".."y:"..v.y..";".."w:"..v.w..";".."h:"..v.h..";".."c:"..v.c[1]..","..v.c[2]..","..v.c[3]..v.c[4]..";|"
		end
		for k,v in pairs(button) do
		end
		newf=love.filesystem.newFile(param[1]..".upm")
		newf:open('w')
		newf:write(newm)
		newf:close()
	end
	console_logadd("unknown command! [given "..str.."]")
end
function console_logadd(str)
	console_log[#console_log+1]=str
	if #console_log>12 then
		table.remove(console_log,1)
	end
end
function plyat(x,y,w,h)
	if x+w>otherplayer.x and x<otherplayer.x+64 then
		if y<otherplayer.y+64 and y+h>otherplayer.y then
			return {x=otherplayer.x,y=otherplayer.y,w=64,h=64,player=otherplayer}
		end
	end
	if x+w>player.x and x<player.x+64 then
		if y<player.y+64 and y+h>player.y then
			return {x=player.x,y=player.y,w=64,h=64,player=player}
		end
	end
	return false
end
function update_btn()
	for b,t in pairs(button) do
		if t.r==r then
			if t.y>t.yy then
				if not plyat(t.x,t.y-0.5,t.w,t.h) then
					t.y=t.y-0.5
				end
			end
			if plyat(t.x,t.y,t.w,t.h) then
				if not t.down then
					t.down=true
					t.a()
				end
				t.a()
				if t.y<t.yy+t.inc then
					t.y=t.y+1
				end
			else
				if t.down then
					t.down=false
					t._n()
				end
				t.n()
			end
		end
	end
end
function love.update(dt)
	if dt < 1/30 then
      love.timer.sleep(1/30 - dt)
	end
	if state==0 then
		
	end
	if state==1 then
		net.process()
	end
	if state==2 then
		if not _edit then
		net.process()
		net.action(pre.."update",tostring(player.x):gsub("-","bz").." "..tostring(player.y):gsub("-","bz"))
		end
		update_btn()
		if love.keyboard.isDown("d") then
			if player.x+64<700 then
				if wallat(player.x,player.y+1,64,64,true) then
					if not wallat(player.x+3,player.y,64,64,true) then
						player.x=player.x+3
					else
						player.x=wallat(player.x+3,player.y,64,64,true).x-64 -- this can be elaborated to fix glitches/cheats with getting stuck in walls.
					end
				else
					if not wallat(player.x+5,player.y,64,64,true) then
						player.x=player.x+5
					else
						player.x=wallat(player.x+5,player.y,64,64,true).x-64 -- this can be elaborated to fix glitches/cheats with getting stuck in walls.
					end
				end
			end
		end
		if love.keyboard.isDown("a") then
			if player.x>0 then
				if wallat(player.x,player.y+1,64,64,true) then
					if not wallat(player.x-3,player.y,64,64,true) then
						player.x=player.x-3
					else
						player.x=wallat(player.x-3,player.y,64,64,true).x+wallat(player.x-3,player.y,64,64,true).w -- this can be elaborated to fix glitches/cheats with getting stuck in walls.
					end
				else
					if not wallat(player.x-5,player.y,64,64,true) then
						player.x=player.x-5
					else
						player.x=wallat(player.x-5,player.y,64,64,true).x+wallat(player.x-5,player.y,64,64,true).w -- this can be elaborated to fix glitches/cheats with getting stuck in walls.
					end
				end	
			end
		end
		if not wallat(player.x,player.y+player.vspeed,64,64,true) then
			player.y=player.y+player.vspeed
			player.vspeed=player.vspeed+0.25
		else
			player.vspeed=0
			if player.vspeed==0 then
			if type(wallat(player.x,player.y+player.vspeed,64,64,true))=="table" then
				player.y=wallat(player.x,player.y+player.vspeed,64,64,true).y-64
			end
			end
		end
		if player.y>3000 then
			if not _edit then
			if pre=="f" then
				player.x,player.y,player.vspeed=pinfo[r].p1x,pinfo[r].p1y,2
			else
				player.x,player.y,player.vspeed=pinfo[r].p2x,pinfo[r].p2y,2
			end
			end
		end
		if _edit then
			for k,v in pairs(edit_objects) do
				if v.type=="resize" then
					if v.d=="diag" then
						v.x=edit_objects[v.as].x+edit_objects[v.as].w+30
						v.y=edit_objects[v.as].y+edit_objects[v.as].h+30
					end
					if v.d=="down" then
						v.x=edit_objects[v.as].x
						v.y=edit_objects[v.as].y+edit_objects[v.as].h+30
					end
					if v.d=="right" then
						v.x=edit_objects[v.as].x+edit_objects[v.as].w+30
						v.y=edit_objects[v.as].y
					end
				end
			end
			if love.mouse.isDown("r") then
				if edit_sid==0 then
					print ("attempting to delete something [not really]")
					return
				end			
			end
			if love.mouse.isDown("l") then
				if edit_sid>0 then			
					edit_objects[edit_sid].x=love.mouse.getX()-edit_relx
					edit_objects[edit_sid].y=love.mouse.getY()-edit_rely
					if edit_objects[edit_sid].type=="resize" then
						if edit_objects[edit_sid].d=="diag" then
							edit_objects[edit_objects[edit_sid].as].w=edit_objects[edit_sid].x-30-edit_objects[edit_objects[edit_sid].as].x
							edit_objects[edit_objects[edit_sid].as].h=edit_objects[edit_sid].y-30-edit_objects[edit_objects[edit_sid].as].y
							edit_objects[edit_sid].x=love.mouse.getX()
							edit_objects[edit_sid].y=love.mouse.getY()
						end
						if edit_objects[edit_sid].d=="down" then
							edit_objects[edit_objects[edit_sid].as].h=edit_objects[edit_sid].y-30-edit_objects[edit_objects[edit_sid].as].y
							edit_objects[edit_sid].y=love.mouse.getY()	
							edit_objects[edit_sid].x=edit_objects[edit_objects[edit_sid].as].x
						end
						if edit_objects[edit_sid].d=="right" then
							edit_objects[edit_objects[edit_sid].as].w=edit_objects[edit_sid].x-30-edit_objects[edit_objects[edit_sid].as].x
							edit_objects[edit_sid].x=love.mouse.getX()	
							edit_objects[edit_sid].y=edit_objects[edit_objects[edit_sid].as].y
						end
					end
				else
				end
				
			end
		end
	end
end
function edit_ishovering()
	for k,v in pairs(edit_objects) do
		if not love.mouse.getX() and love.mouse.getY() then return end
		if love.mouse.getX()>v.x and love.mouse.getX()<v.x+v.w then
			if love.mouse.getY()>v.y and love.mouse.getY()<v.y+v.h then
				return v
			end
		end
	end
	return nil
end
function love.mousereleased(x,y,btn)
	if _edit then
		if btn=="r" then
			if not edit_ishovering() == edit_objects[edit_sid] then
				binds[#binds+1]={edit_objects[edit_sid],edit_ishovering()}
				print("attaching a bind")
			end
		end
		if btn=="l" then
			if edit_ishovering() then
				if edit_ishovering().type=="resize" then
					if edit_ishovering().obj==edit_objects[edit_sid] and edit_objects[edit_sid].type ~= "player"  then	
						edit_ishovering().obj.w=edit_objects[edit_objects[edit_sid].as].w
						edit_ishovering().obj.h=edit_objects[edit_objects[edit_sid].as].h
					end
				end
				if edit_objects[edit_sid].type=="wall"  then
					edit_objects[edit_sid].obj.x=edit_objects[edit_sid].x
					edit_objects[edit_sid].obj.y=edit_objects[edit_sid].y
					edit_objects[edit_sid].obj.w=edit_objects[edit_sid].w
					edit_objects[edit_sid].obj.h=edit_objects[edit_sid].h
					edit_objects[edit_sid].obj.c=edit_objects[edit_sid].c
					print("releasing object from mouse, type "..edit_objects[edit_sid].type)
				end
				if edit_objects[edit_sid].type=="player"  then
					edit_objects[edit_sid].obj.x=edit_objects[edit_sid].x
					edit_objects[edit_sid].obj.y=edit_objects[edit_sid].y
					edit_objects[edit_sid].obj.vspeed=0
					print("releasing object from mouse, type "..edit_objects[edit_sid].type)
				end
				if edit_objects[edit_sid].type=="resize" then
					edit_objects[edit_objects[edit_sid].as].obj.w=edit_objects[edit_objects[edit_sid].as].w
					edit_objects[edit_objects[edit_sid].as].obj.h=edit_objects[edit_objects[edit_sid].as].h
				end
			end
		end
	end
end
function love.mousepressed(x,y,btn)
	if _edit then
		if btn=="l" then
			edit_sid=0
			for k,v in pairs(edit_objects) do
				if love.mouse.getX()>v.x and love.mouse.getX()<v.x+v.w then
					if love.mouse.getY()>v.y and love.mouse.getY()<v.y+v.h then
						if v.type=="newobj" then
							edit_objects[#edit_objects+1]={type="wall",c={130,10,30,160},x=0,y=0,w=100,h=50}
							n,l=edit_objects[#edit_objects],#edit_objects
							wall[#wall+1]={x=0,y=0,w=100,h=50,c={130,10,30,160}}
							edit_objects[#edit_objects+1]={type="resize",c={255,30,30,90},w=30,h=30,x=0,y=0,d="right",as=l}
							edit_objects[#edit_objects+1]={type="resize",c={255,30,30,90},w=30,h=30,x=0,y=0,d="diag",as=l}
							edit_objects[#edit_objects+1]={type="resize",c={255,30,30,90},w=30,h=30,x=0,y=0,d="down",as=l}
							n.obj=wall[#wall]
							edit_sid=l
							return
						end
						edit_sid=k
						edit_relx=love.mouse.getX()-v.x
						edit_rely=love.mouse.getY()-v.y
						return v
					end
				end
			end
		end
		return nil
	end
end
function love.keypressed(key)
	if love.keyboard.isDown("rshift") or love.keyboard.isDown("rshift") then
		if key=="-" then
			key="_"
		end
	end
	if key=="`" then
		_debug=not _debug
		return
	end
	if key:len()==1 then 
		if _edit and edit_sid==2 then return end
		if not _debug then
			k_string=k_string..key 
		else
			c_string=c_string..key 
		end
	end
	if key=="return" then
		if _debug then
			console(c_string)
			c_string=""
		end
	end
	if key=="backspace" then
		if _debug then c_string=c_string:sub(1,c_string:len()-1) end
	end
	if key=="escape" then love.event.push("quit") end
	if key=="f3" then
		if not _debug then return end
		k_string=""
	end
	if _debug then return end
	if state==0 then
		if key=="return" then
			print("attempting connection to ["..k_string.."]")
			net.connect(k_string,5137)
			connected=k_string
			net.lostconnect(function(err)
				error("connection failure.")
			end )
			net.call("joined")
			state=1
		end
	end
	if state==2 then
		if key=="f1" then
		vs= not vs 
			love.graphics.setMode(ww,wh,fs,vs,aa)
		end
		if key==" " or key=="w" then
			if wallat(player.x,player.y+1,64,64,true) then
				player.vspeed=-7
			end
		end
	end
	
end
function onoff(bool)
	if bool then return "on" else return "off" end
end
function love.draw()
	if _debug then
	love.graphics.setColor(255,255,255,255)
	love.graphics.print(love.timer.getFPS().." fps",5,5)
	love.graphics.print("dimensions: "..ww.." by "..wh,5,15)
	love.graphics.print("vertical sync "..onoff(vs),5,25)
	love.graphics.print("FSAA "..aa.."x",5,35)
	love.graphics.setColor(50,50,100,255)
	love.graphics.print("-----",5,40)
	love.graphics.setColor(255,50,50,130)
	love.graphics.print("otherplayer "..otherplayer.x.." "..otherplayer.y,otherplayer.x,otherplayer.y-10)
	love.graphics.setColor(50,50,255,130)
	love.graphics.print("player "..player.x.." "..player.y,player.x,player.y-10)
	love.graphics.print(player.vspeed,player.x,player.y+70)
	love.graphics.setColor(255,255,255,180)
	love.graphics.line(player.x,player.y,player.x,player.y+player.vspeed)
	love.graphics.setColor(50,50,50,150)
	love.graphics.rectangle("fill",320,0,320,200)
	love.graphics.setColor(60,60,60,70)
	love.graphics.rectangle("fill",320,180,320,20)
	love.graphics.setColor(255,255,255,200)
	for k,v in pairs(console_log) do
		love.graphics.print(v,340,k*12)
	end
	love.graphics.setColor(255,255,255,255)
	love.graphics.print(c_string,323,181)
	end
	if state==0 then
		love.graphics.setColor(30,30,130,100)
		love.graphics.rectangle("fill",0,wh/2-20,ww,40)
		love.graphics.setColor(150,150,150,200)
		love.graphics.print(k_string,ww/2-100,wh/2-10)
	end
	if state==1 then
		love.graphics.setColor(30,30,130,100)
		love.graphics.rectangle("fill",0,wh/2-20,ww,40)
		love.graphics.setColor(150,150,150,200)
		love.graphics.print(k_string,ww/2-100,wh/2-10)
		love.graphics.print("connected to "..connected,5,45)
		love.graphics.print("waiting for other player..",5,55)
	end
	if state==2 then
		if not _edit then
		if not r then
			love.graphics.setColor(40,40,255,255)
			love.graphics.print("receiving map data..",320,240)
			return
		end
		end
		if not _edit then
			cx,cy=(player.x-(ww/2)),(player.y-(wh/2))
		else
			if love.keyboard.isDown("v") then
				cx,cy=(otherplayer.x-(ww/2)),(otherplayer.y-(wh/2))
			end
		end
		if cx<0 then cx=0 end
		if cx+ww>700 then cx=(700-ww) end
		if cy<0 then cy=0 end
		if cy+wh>3000 then cy=(3000-wh) end
		love.graphics.print("connected to "..connected,5,45)
		love.graphics.print("in game",5,55)
		if _edit then
			if love.keyboard.isDown("c") then love.graphics.translate(-cx,-cy) end
		else
			love.graphics.translate(-cx,-cy)
		end
		love.graphics.setColor(130,130,255,230)
		love.graphics.rectangle("fill",player.x,player.y,64,64)
		love.graphics.setColor(255,100,100,220)
		love.graphics.rectangle("fill",otherplayer.x,otherplayer.y,64,64)
		love.graphics.setColor(150,150,150,100)
		for b,t in pairs(button) do
			if t.r==r then
			love.graphics.setColor(t.c)
			love.graphics.rectangle("fill",t.x,t.y,t.w,t.h)
			end
		end
		for k,v in pairs(wall) do
			if v.r==r then
			love.graphics.setColor(v.c)
			love.graphics.rectangle("fill",v.x,v.y,v.w,v.h)
			end
		end
		love.graphics.setColor(255,255,255,255)
		if _edit then
			for k,v in pairs(edit_objects) do
				love.graphics.setColor(v.c)
				love.graphics.rectangle("fill",v.x,v.y,v.w,v.h)
				if k==edit_sid then	
					if not v.type=="player" and not v.type=="resize" then
						love.graphics.rectangle("fill",v.x+v.w+30,v.y,30,30)
						love.graphics.rectangle("fill",v.x+v.w+30,v.y+v.h+30,30,30)
						love.graphics.rectangle("fill",v.x,v.y+v.h+30,30,30)
					end
					love.graphics.setColor(255,255,255,50)
					love.graphics.rectangle("fill",v.x,v.y,v.w,v.h)
				end
			end
			love.graphics.setColor(30,30,30,30)
			for k=1,480/10 do
				love.graphics.line(0,k*10,640,k*10)
			end
			for k=1,640/10 do
				love.graphics.line(k*10,0,k*10,480)
			end
		end
	end
	
end